import {
	Button,
	Input,
	Checkbox,
	Modal,
	Select,
	Spin,
	Icon,
	Collapse,
	Tooltip,
	Tabs,
	Switch,
	Row,
	Col,
	Alert
} from "ant-design-vue";
import constants from "ysrc/utils/variable";
import AceEditor from "client/components/AceEditor/AceEditor";
import { _ } from "@ventose/ui";
import { isJson, deepCopyJson, json5_parse } from "../../common.js";
import axios from "axios";
import ModalPostman from "../ModalPostman/index.js";
import CheckCrossInstall, { initCrossRequest } from "./CheckCrossInstall.js";
import "./Postman.scss";
import ProjectEnv from "../../containers/Project/Setting/ProjectEnv/index.js";
import json5 from "json5";
const {
	handleParamsValue,
	ArrayToObject,
	schemaValidator
} = require("common/utils.js");
const {
	handleParams,
	checkRequestBodyIsRaw,
	handleContentType,
	crossRequest,
	checkNameIsExistInArray
} = require("common/postmanLib.js");

const plugin = require("client/plugin.js");

const createContext = require("common/createContext");

const HTTP_METHOD = constants.HTTP_METHOD;
const InputGroup = Input.Group;
const Option = Select.Option;
const Panel = Collapse.Panel;

export const InsertCodeMap = [
	{
		code: "assert.equal(status, 200)",
		title: "断言 httpCode 等于 200"
	},
	{
		code: "assert.equal(body.code, 0)",
		title: "断言返回数据 code 是 0"
	},
	{
		code: "assert.notEqual(status, 404)",
		title: "断言 httpCode 不是 404"
	},
	{
		code: "assert.notEqual(body.code, 40000)",
		title: "断言返回数据 code 不是 40000"
	},
	{
		code: 'assert.deepEqual(body, {"code": 0})',
		title: '断言对象 body 等于 {"code": 0}'
	},
	{
		code: 'assert.notDeepEqual(body, {"code": 0})',
		title: '断言对象 body 不等于 {"code": 0}'
	}
];

const ParamsNameComponent = props => {
	const { example, desc, name } = props;
	const isNull = !example && !desc;
	const TooltipTitle = () => {
		return (
			<div>
				{example && (
					<div>
						示例： <span class="table-desc">{example}</span>
					</div>
				)}
				{desc && (
					<div>
						备注： <span class="table-desc">{desc}</span>
					</div>
				)}
			</div>
		);
	};

	return (
		<div>
			{isNull ? (
				<aInput disabled value={name} class="key" />
			) : (
				<aTooltip placement="topLeft" title={<aTooltipTitle />}>
					<aInput disabled value={name} class="key" />
				</aTooltip>
			)}
		</div>
	);
};
ParamsNameComponent.propTypes = {
	example: PropTypes.string,
	desc: PropTypes.string,
	name: PropTypes.string
};
export default class Run extends Component {
	static propTypes = {
		data: PropTypes.object, //接口原有数据
		save: PropTypes.func, //保存回调方法
		type: PropTypes.string, //enum[case, inter], 判断是在接口页面使用还是在测试集
		curUid: PropTypes.number.isRequired,
		interfaceId: PropTypes.number.isRequired,
		projectId: PropTypes.number.isRequired
	};

	constructor(props) {
		super(props);
		this.state = {
			loading: false,
			resStatusCode: null,
			test_valid_msg: null,
			resStatusText: null,
			case_env: "",
			mock_verify: false,
			enable_script: false,
			test_script: "",
			hasPlugin: true,
			inputValue: "",
			cursurPosition: { row: 1, column: -1 },
			envModalVisible: false,
			test_res_header: null,
			test_res_body: null,
			autoPreviewHTML: true,
			...this.props.data
		};
	}

	get testResponseBodyIsHTML() {
		const hd = this.state.test_res_header;
		return (
			hd != null &&
			typeof hd === "object" &&
			String(hd["Content-Type"] || hd["content-type"]).indexOf("text/html") !==
				-1
		);
	}

	checkInterfaceData(data) {
		if (!data || typeof data !== "object" || !data._id) {
			return false;
		}
		return true;
	}

	// 整合header信息
	handleReqHeader = (value, env) => {
		let index = value
			? env.findIndex(item => {
					return item.name === value;
			  })
			: 0;
		index = index === -1 ? 0 : index;

		let req_header = [].concat(this.props.data.req_headers || []);
		let header = [].concat(env[index].header || []);
		header.forEach(item => {
			if (!checkNameIsExistInArray(item.name, req_header)) {
				item = {
					...item,
					abled: true
				};
				req_header.push(item);
			}
		});
		req_header = req_header.filter(item => {
			return item && typeof item === "object";
		});
		return req_header;
	};

	selectDomain = value => {
		let headers = this.handleReqHeader(value, this.state.env);
		this.setState({
			case_env: value,
			req_headers: headers
		});
	};

	async initState(data) {
		if (!this.checkInterfaceData(data)) {
			return null;
		}

		const { req_body_other, req_body_type, req_body_is_json_schema } = data;
		let body = req_body_other;
		// 运行时才会进行转换
		if (
			this.props.type === "inter" &&
			req_body_type === "json" &&
			req_body_other &&
			req_body_is_json_schema
		) {
			let schema = {};
			try {
				schema = json5.parse(req_body_other);
			} catch (e) {
				console.log("e", e);
				return;
			}
			let result = await axios.post("/api/interface/schema2json", {
				schema: schema,
				required: true
			});
			body = JSON.stringify(result.data);
		}

		let example = {};
		if (this.props.type === "inter") {
			example = ["req_headers", "req_query", "req_body_form"].reduce(
				(res, key) => {
					res[key] = (data[key] || []).map(item => {
						if (
							item.type !== "file" && // 不是文件类型
							(item.value == null || item.value === "") && // 初始值为空
							item.example != null // 有示例值
						) {
							item.value = item.example;
						}
						return item;
					});
					return res;
				},
				{}
			);
		}

		this.setState(
			{
				...this.state,
				test_res_header: null,
				test_res_body: null,
				...data,
				...example,
				req_body_other: body,
				resStatusCode: null,
				test_valid_msg: null,
				resStatusText: null
			},
			() =>
				this.props.type === "inter" &&
				this.initEnvState(data.case_env, data.env)
		);
	}

	initEnvState(case_env, env) {
		let headers = this.handleReqHeader(case_env, env);

		this.setState(
			{
				req_headers: headers,
				env: env
			},
			() => {
				let s = !_.find(env, item => item.name === this.state.case_env);
				if (!this.state.case_env || s) {
					this.setState({
						case_env: this.state.env[0].name
					});
				}
			}
		);
	}

	UNSAFE_componentWillMount() {
		this._crossRequestInterval = initCrossRequest(hasPlugin => {
			this.setState({
				hasPlugin: hasPlugin
			});
		});
		this.initState(this.props.data);
	}

	componentWillUnmount() {
		clearInterval(this._crossRequestInterval);
	}

	componentWillReceiveProps(nextProps) {
		if (
			this.checkInterfaceData(nextProps.data) &&
			this.checkInterfaceData(this.props.data)
		) {
			if (nextProps.data._id !== this.props.data._id) {
				this.initState(nextProps.data);
			} else if (
				nextProps.data.interface_up_time !== this.props.data.interface_up_time
			) {
				this.initState(nextProps.data);
			}
			if (nextProps.data.env !== this.props.data.env) {
				this.initEnvState(this.state.case_env, nextProps.data.env);
			}
		}
	}

	handleValue(val, global) {
		let globalValue = ArrayToObject(global);
		return handleParamsValue(val, {
			global: globalValue
		});
	}

	onOpenTest = d => {
		this.setState({
			test_script: d.text
		});
	};

	handleInsertCode = code => {
		this.aceEditor.editor.insertCode(code);
	};

	handleRequestBody = d => {
		this.setState({
			req_body_other: d.text
		});
	};

	reqRealInterface = async () => {
		if (this.state.loading === true) {
			this.setState({
				loading: false
			});
			return null;
		}
		this.setState({
			loading: true
		});

		let options = handleParams(this.state, this.handleValue);
		let result;

		await plugin.emitHook("before_request", options, {
			type: this.props.type,
			caseId: options.caseId,
			projectId: this.props.projectId,
			interfaceId: this.props.interfaceId
		});
		try {
			options.taskId = this.props.curUid;
			options.interfaceData = this.state;
			console.log("run crossRequest", options);
			result = await crossRequest(
				options,
				options.pre_script || this.state.pre_script,
				options.after_script || this.state.after_script,
				createContext(
					this.props.curUid,
					this.props.projectId,
					this.props.interfaceId
				)
			);

			await plugin.emitHook("after_request", result, {
				type: this.props.type,
				caseId: options.caseId,
				projectId: this.props.projectId,
				interfaceId: this.props.interfaceId
			});

			result = {
				...result,
				header: result.res.header,
				body: result.res.body,
				status: result.res.status,
				statusText: result.res.statusText,
				runTime: result.runTime
			};
		} catch (data) {
			result = {
				...data,
				header: data.header,
				body: data.body,
				status: null,
				statusText: data.message
			};
		}
		if (this.state.loading === true) {
			this.setState({
				loading: false
			});
		} else {
			return null;
		}

		let tempJson = result.body;
		if (tempJson && typeof tempJson === "object") {
			result.body = JSON.stringify(tempJson, null, "  ");
			this.setState({
				res_body_type: "json"
			});
		} else if (isJson(result.body)) {
			this.setState({
				res_body_type: "json"
			});
		}

		// 对 返回值数据结构 和定义的 返回数据结构 进行 格式校验
		let validResult = this.resBodyValidator(this.props.data, result.body);
		if (!validResult.valid) {
			this.setState({ test_valid_msg: `返回参数 ${validResult.message}` });
		} else {
			this.setState({ test_valid_msg: "" });
		}
		let state = {};
		try {
			state = {
				resStatusCode: result.status,
				resStatusText: result.statusText,
				test_res_header: `/* ===============请求参数================= */
${JSON.stringify(
	_.omit(result.req, ["interfaceData", "taskId", "timeout", "caseId"]),
	null,
	2
)}
/* ===============请求参数================= */
${JSON.stringify(result.header, null, 2)}
`,
				test_res_body: result.body
			};
		} catch (error) {
			console.log(error);
		}
		this.setState(state);
	};

	// 返回数据与定义数据的比较判断
	resBodyValidator = (interfaceData, test_res_body) => {
		const { res_body_type, res_body_is_json_schema, res_body } = interfaceData;
		let validResult = { valid: true };

		if (res_body_type === "json" && res_body_is_json_schema) {
			const schema = json5_parse(res_body);
			const params = json5_parse(test_res_body);
			validResult = schemaValidator(schema, params);
		}

		return validResult;
	};

	changeParam = (name, v, index, key) => {
		key = key || "value";
		const pathParam = deepCopyJson(this.state[name]);

		pathParam[index][key] = v;
		if (key === "value") {
			pathParam[index].enable = !!v;
		}
		this.setState({
			[name]: pathParam
		});
	};

	changeBody = (v, index, key) => {
		const bodyForm = deepCopyJson(this.state.req_body_form);
		key = key || "value";
		if (key === "value") {
			bodyForm[index].enable = !!v;
			if (bodyForm[index].type === "file") {
				bodyForm[index].value = "file_" + index;
			} else {
				bodyForm[index].value = v;
			}
		} else if (key === "enable") {
			bodyForm[index].enable = v;
		}
		this.setState({ req_body_form: bodyForm });
	};

	// 模态框的相关操作
	showModal = (val, index, type) => {
		let inputValue = "";
		let cursurPosition;
		if (type === "req_body_other") {
			// req_body
			let editor = this.aceEditor.editor.editor;
			cursurPosition = editor.session.doc.positionToIndex(
				editor.selection.getCursor()
			);
			// 获取选中的数据
			inputValue = this.getInstallValue(val || "", cursurPosition).val;
		} else {
			// 其他input 输入
			let oTxt1 = document.getElementById(`${type}_${index}`);
			cursurPosition = oTxt1.selectionStart;
			inputValue = this.getInstallValue(val || "", cursurPosition).val;
			// cursurPosition = {row: 1, column: position}
		}

		this.setState({
			modalVisible: true,
			inputIndex: index,
			inputValue,
			cursurPosition,
			modalType: type
		});
	};

	// 点击插入
	handleModalOk = val => {
		const { inputIndex, modalType } = this.state;
		if (modalType === "req_body_other") {
			this.changeInstallBody(modalType, val);
		} else {
			this.changeInstallParam(modalType, val, inputIndex);
		}

		this.setState({ modalVisible: false });
	};

	// 根据鼠标位置往req_body中动态插入数据
	changeInstallBody = (type, value) => {
		const pathParam = deepCopyJson(this.state[type]);
		// console.log(pathParam)
		let oldValue = pathParam || "";
		let newValue = this.getInstallValue(oldValue, this.state.cursurPosition);
		let left = newValue.left;
		let right = newValue.right;
		this.setState({
			[type]: `${left}${value}${right}`
		});
	};

	// 获取截取的字符串
	getInstallValue = (oldValue, cursurPosition) => {
		let left = oldValue.substr(0, cursurPosition);
		let right = oldValue.substr(cursurPosition);

		let leftPostion = left.lastIndexOf("{{");
		let leftPostion2 = left.lastIndexOf("}}");
		let rightPostion = right.indexOf("}}");
		// console.log(leftPostion, leftPostion2,rightPostion, rightPostion2);
		let val = "";
		// 需要切除原来的变量
		if (
			leftPostion !== -1 &&
			rightPostion !== -1 &&
			leftPostion > leftPostion2
		) {
			left = left.substr(0, leftPostion);
			right = right.substr(rightPostion + 2);
			val = oldValue.substring(leftPostion, cursurPosition + rightPostion + 2);
		}
		return {
			left,
			right,
			val
		};
	};

	// 根据鼠标位置动态插入数据
	changeInstallParam = (name, v, index, key) => {
		key = key || "value";
		const pathParam = deepCopyJson(this.state[name]);
		let oldValue = pathParam[index][key] || "";
		let newValue = this.getInstallValue(oldValue, this.state.cursurPosition);
		let left = newValue.left;
		let right = newValue.right;
		pathParam[index][key] = `${left}${v}${right}`;
		this.setState({
			[name]: pathParam
		});
	};

	// 取消参数插入
	handleModalCancel = () => {
		this.setState({ modalVisible: false, cursurPosition: -1 });
	};

	// 环境变量模态框相关操作
	showEnvModal = () => {
		this.setState({
			envModalVisible: true
		});
	};

	handleEnvOk = (newEnv, index) => {
		this.setState({
			envModalVisible: false,
			case_env: newEnv[index].name
		});
	};

	handleEnvCancel = () => {
		this.setState({
			envModalVisible: false
		});
	};

	render() {
		const {
			method,
			env,
			path,
			req_params = [],
			req_headers = [],
			req_query = [],
			req_body_type,
			req_body_form = [],
			loading,
			case_env,
			inputValue,
			hasPlugin
		} = this.state;
		// console.log(env);
		return (
			<div class="interface-test postman">
				{this.state.modalVisible && (
					<aModalPostman
						visible={this.state.modalVisible}
						handleCancel={this.handleModalCancel}
						handleOk={this.handleModalOk}
						inputValue={inputValue}
						envType={this.props.type}
						id={+this.state._id}
					/>
				)}

				{this.state.envModalVisible && (
					<aModal
						title="环境设置"
						visible={this.state.envModalVisible}
						onOk={this.handleEnvOk}
						onCancel={this.handleEnvCancel}
						footer={null}
						width={800}
						class="env-modal">
						<ProjectEnv
							projectId={this.props.data.project_id}
							onOk={this.handleEnvOk}
						/>
					</aModal>
				)}
				<CheckCrossInstall hasPlugin={hasPlugin} />

				<div class="url">
					<aInputGroup compact style={{ display: "flex" }}>
						<Select disabled value={method} style={{ flexBasis: 60 }}>
							{Object.keys(HTTP_METHOD).map(name => {
								<Option value={name.toUpperCase()}>
									{name.toUpperCase()}
								</Option>;
							})}
						</Select>
						<Select
							value={case_env}
							style={{ flexBasis: 180, flexGrow: 1 }}
							onSelect={this.selectDomain}>
							{env.map((item, index) => (
								<Option value={item.name} key={index}>
									{item.name + "：" + item.domain}
								</Option>
							))}
							<Option
								value="环境配置"
								disabled
								style={{ cursor: "pointer", color: "#2395f1" }}>
								<aButton type="primary" onClick={this.showEnvModal}>
									环境配置
								</aButton>
							</Option>
						</Select>

						<aInput
							disabled
							value={path}
							onChange={this.changePath}
							spellCheck="false"
							style={{ flexBasis: 180, flexGrow: 1 }}
						/>
					</aInputGroup>

					<aTooltip
						placement="bottom"
						title={(() => {
							if (hasPlugin) {
								return "发送请求";
							} else {
								return "请安装 cross-request 插件";
							}
						})()}>
						<aButton
							onClick={this.reqRealInterface}
							type="primary"
							style={{ marginLeft: 10 }}
							icon={loading ? "loading" : ""}>
							{loading ? "取消" : "发送"}
						</aButton>
					</aTooltip>

					<aTooltip
						placement="bottom"
						title={() => {
							return this.props.type === "inter"
								? "保存到测试集"
								: "更新该用例";
						}}>
						<aButton
							onClick={this.props.save}
							type="primary"
							style={{ marginLeft: 10 }}>
							{this.props.type === "inter" ? "保存" : "更新"}
						</aButton>
					</aTooltip>
				</div>

				<aCollapse defaultActiveKey={["0", "1", "2", "3"]} bordered={true}>
					<Panel
						header="PATH PARAMETERS"
						key="0"
						class={req_params.length === 0 ? "hidden" : ""}>
						{req_params.map((item, index) => {
							return (
								<div key={index} class="key-value-wrap">
									{/* <aTooltip
                    placement="topLeft"
                    title={<aTooltipContent example={item.example} desc={item.desc} />}
                  >
                    <aInput disabled value={item.name} class="key" />
                  </aTooltip> */}
									<ParamsNameComponent
										example={item.example}
										desc={item.desc}
										name={item.name}
									/>
									<span class="eq-symbol">=</span>
									<aInput
										value={item.value}
										class="value"
										onChange={e =>
											this.changeParam("req_params", e.target.value, index)
										}
										placeholder="参数值"
										id={`req_params_${index}`}
										addonAfter={
											<aIcon
												type="edit"
												onClick={() =>
													this.showModal(item.value, index, "req_params")
												}
											/>
										}
									/>
								</div>
							);
						})}
						<aButton
							style={{ display: "none" }}
							type="primary"
							icon="plus"
							onClick={this.addPathParam}>
							添加Path参数
						</aButton>
					</Panel>
					<Panel
						header="QUERY PARAMETERS"
						key="1"
						class={req_query.length === 0 ? "hidden" : ""}>
						{req_query.map((item, index) => {
							return (
								<div key={index} class="key-value-wrap">
									{/* <aTooltip
                    placement="topLeft"
                    title={<aTooltipContent example={item.example} desc={item.desc} />}
                  >
                    <aInput disabled value={item.name} class="key" />
                  </aTooltip> */}
									<ParamsNameComponent
										example={item.example}
										desc={item.desc}
										name={item.name}
									/>
									&nbsp;
									{item.required == 1 ? (
										<Checkbox class="params-enable" checked={true} disabled />
									) : (
										<Checkbox
											class="params-enable"
											checked={item.enable}
											onChange={e =>
												this.changeParam(
													"req_query",
													e.target.checked,
													index,
													"enable"
												)
											}
										/>
									)}
									<span class="eq-symbol">=</span>
									<aInput
										value={item.value}
										class="value"
										onChange={e =>
											this.changeParam("req_query", e.target.value, index)
										}
										placeholder="参数值"
										id={`req_query_${index}`}
										addonAfter={
											<aIcon
												type="edit"
												onClick={() =>
													this.showModal(item.value, index, "req_query")
												}
											/>
										}
									/>
								</div>
							);
						})}
						<aButton
							style={{ display: "none" }}
							type="primary"
							icon="plus"
							onClick={this.addQuery}>
							添加Query参数
						</aButton>
					</Panel>
					<Panel
						header="HEADERS"
						key="2"
						class={req_headers.length === 0 ? "hidden" : ""}>
						{req_headers.map((item, index) => {
							return (
								<div key={index} class="key-value-wrap">
									{/* <aTooltip
                    placement="topLeft"
                    title={<aTooltipContent example={item.example} desc={item.desc} />}
                  >
                    <aInput disabled value={item.name} class="key" />
                  </aTooltip> */}
									<ParamsNameComponent
										example={item.example}
										desc={item.desc}
										name={item.name}
									/>
									<span class="eq-symbol">=</span>
									<aInput
										value={item.value}
										disabled={!!item.abled}
										class="value"
										onChange={e =>
											this.changeParam("req_headers", e.target.value, index)
										}
										placeholder="参数值"
										id={`req_headers_${index}`}
										addonAfter={
											!item.abled && (
												<aIcon
													type="edit"
													onClick={() =>
														this.showModal(item.value, index, "req_headers")
													}
												/>
											)
										}
									/>
								</div>
							);
						})}
						<aButton
							style={{ display: "none" }}
							type="primary"
							icon="plus"
							onClick={this.addHeader}>
							添加Header
						</aButton>
					</Panel>
					<Panel
						header={
							<div style={{ display: "flex", justifyContent: "space-between" }}>
								<aTooltip title="F9 全屏编辑">BODY(F9)</aTooltip>
							</div>
						}
						key="3"
						class={
							HTTP_METHOD[method].request_body &&
							((req_body_type === "form" && req_body_form.length > 0) ||
								req_body_type !== "form")
								? "POST"
								: "hidden"
						}>
						<div
							style={{
								display: checkRequestBodyIsRaw(method, req_body_type)
									? "block"
									: "none"
							}}>
							{req_body_type === "json" && (
								<div class="adv-button">
									<aButton
										onClick={() =>
											this.showModal(
												this.state.req_body_other,
												0,
												"req_body_other"
											)
										}>
										高级参数设置
									</aButton>
									<aTooltip title="高级参数设置只在json字段值中生效">
										{"  "}
										<xIcon icon="question-circle-o" />
									</aTooltip>
								</div>
							)}

							<AceEditor
								class="pretty-editor"
								ref={editor => (this.aceEditor = editor)}
								data={this.state.req_body_other}
								mode={req_body_type === "json" ? null : "text"}
								onChange={this.handleRequestBody}
								fullScreen={true}
							/>
						</div>

						{HTTP_METHOD[method].request_body && req_body_type === "form" && (
							<div>
								{req_body_form.map((item, index) => {
									return (
										<div key={index} class="key-value-wrap">
											{/* <aTooltip
                          placement="topLeft"
                          title={<aTooltipContent example={item.example} desc={item.desc} />}
                        >
                          <aInput disabled value={item.name} class="key" />
                        </aTooltip> */}
											<ParamsNameComponent
												example={item.example}
												desc={item.desc}
												name={item.name}
											/>
											&nbsp;
											{item.required == 1 ? (
												<Checkbox
													class="params-enable"
													checked={true}
													disabled
												/>
											) : (
												<Checkbox
													class="params-enable"
													checked={item.enable}
													onChange={e =>
														this.changeBody(e.target.checked, index, "enable")
													}
												/>
											)}
											<span class="eq-symbol">=</span>
											{item.type === "file" ? (
												"因Chrome最新版安全策略限制，不再支持文件上传"
											) : (
												// <aInput
												//   type="file"
												//   id={'file_' + index}
												//   onChange={e => this.changeBody(e.target.value, index, 'value')}
												//   multiple
												//   class="value"
												// />
												<aInput
													value={item.value}
													class="value"
													onChange={e => this.changeBody(e.target.value, index)}
													placeholder="参数值"
													id={`req_body_form_${index}`}
													addonAfter={
														<aIcon
															type="edit"
															onClick={() =>
																this.showModal(
																	item.value,
																	index,
																	"req_body_form"
																)
															}
														/>
													}
												/>
											)}
										</div>
									);
								})}
								<aButton
									style={{ display: "none" }}
									type="primary"
									icon="plus"
									onClick={this.addBody}>
									添加Form参数
								</aButton>
							</div>
						)}
						{HTTP_METHOD[method].request_body && req_body_type === "file" && (
							<div>
								<aInput type="file" id="single-file" />
							</div>
						)}
					</Panel>
				</aCollapse>

				<Tabs size="large" defaultActiveKey="res" class="response-tab">
					<Tabs.TabPane tab="Response" key="res">
						<aSpin spinning={this.state.loading}>
							<h2
								style={{ display: this.state.resStatusCode ? "" : "none" }}
								class={
									"res-code " +
									(this.state.resStatusCode >= 200 &&
									this.state.resStatusCode < 400 &&
									!this.state.loading
										? "success"
										: "fail")
								}>
								{this.state.resStatusCode + "  " + this.state.resStatusText}
							</h2>
							<div>
								<a
									rel="noopener noreferrer"
									target="_blank"
									href="https://juejin.im/post/5c888a3e5188257dee0322af">
									YApi 新版如何查看 http 请求数据
								</a>
							</div>
							{this.state.test_valid_msg && (
								<Alert
									message={
										<span>
											Warning &nbsp;
											<aTooltip title="针对定义为 json schema 的返回数据进行格式校验">
												<xIcon icon="question-circle-o" />
											</aTooltip>
										</span>
									}
									type="warning"
									showIcon
									description={this.state.test_valid_msg}
								/>
							)}

							<div class="container-header-body">
								<div class="header">
									<div class="container-title">
										<h4>Headers</h4>
									</div>
									<AceEditor
										callback={editor => {
											editor.renderer.setShowGutter(false);
										}}
										readOnly={true}
										class="pretty-editor-header"
										data={this.state.test_res_header}
										mode="json"
									/>
								</div>
								<div class="resizer">
									<div class="container-title">
										<h4 style={{ visibility: "hidden" }}>1</h4>
									</div>
								</div>
								<div class="body">
									<div class="container-title">
										<h4>Body</h4>
										<Checkbox
											checked={this.state.autoPreviewHTML}
											onChange={e =>
												this.setState({ autoPreviewHTML: e.target.checked })
											}>
											<span>自动预览HTML</span>
										</Checkbox>
									</div>
									{this.state.autoPreviewHTML && this.testResponseBodyIsHTML ? (
										<iframe
											class="pretty-editor-body"
											srcDoc={this.state.test_res_body}
										/>
									) : (
										<AceEditor
											readOnly={true}
											class="pretty-editor-body"
											data={this.state.test_res_body}
											mode={handleContentType(this.state.test_res_header)}
										/>
									)}
								</div>
							</div>
						</aSpin>
					</Tabs.TabPane>
					{this.props.type === "case" ? (
						<Tabs.TabPane
							class="response-test"
							tab={
								<aTooltip title="测试脚本，可断言返回结果，使用方法请查看文档">
									Test
								</aTooltip>
							}
							key="test">
							<h3 style={{ margin: "5px" }}>
								&nbsp;是否开启:&nbsp;
								<Switch
									checked={this.state.enable_script}
									onChange={e => this.setState({ enable_script: e })}
								/>
							</h3>
							<p style={{ margin: "10px" }}>
								注：Test 脚本只有做自动化测试才执行
							</p>
							<aRow>
								<aCol span="18">
									<AceEditor
										onChange={this.onOpenTest}
										class="case-script"
										data={this.state.test_script}
										ref={aceEditor => {
											this.aceEditor = aceEditor;
										}}
									/>
								</aCol>
								<aCol span="6">
									<div class="insert-code">
										{InsertCodeMap.map(item => {
											return (
												<div
													style={{ cursor: "pointer" }}
													class="code-item"
													key={item.title}
													onClick={() => {
														this.handleInsertCode("\n" + item.code);
													}}>
													{item.title}
												</div>
											);
										})}
									</div>
								</aCol>
							</aRow>
						</Tabs.TabPane>
					) : null}
				</Tabs>
			</div>
		);
	}
}
